package com.wzs.rpc.server.tcp;

import com.wzs.rpc.protocol.ProtocolConstant;
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.parsetools.RecordParser;

/**
 * 装饰器，利用Vertx框架的RecordParser解决粘包和拆包问题
 * 采用的是固定消息长度的方式，先读取固定长度的header，再根据其中的body长度读取body
 */
public class TcpBufferHandlerWrapper implements Handler<Buffer> {
    private final RecordParser recordParser;

    public TcpBufferHandlerWrapper(Handler<Buffer> handler) {
        recordParser = initRecordParser(handler);
    }

    @Override
    public void handle(Buffer buffer) {
        recordParser.handle(buffer);
    }

    private RecordParser initRecordParser(Handler<Buffer> handler) {
        RecordParser recordParser = RecordParser.newFixed(ProtocolConstant.MESSAGE_HEADER_LENGTH);
        recordParser.setOutput(new Handler<Buffer>() {
            //是否开始读取body
            boolean flag = false;
            //存储完整的header+body
            Buffer resultBuffer = Buffer.buffer();

            @Override
            public void handle(Buffer buffer) {
                //读取header
                if (!flag) {
                    int bodyLength = buffer.getInt(13);
                    recordParser.fixedSizeMode(bodyLength);
                    resultBuffer.appendBuffer(buffer);
                    flag = true;
                //读取body
                } else {
                    recordParser.fixedSizeMode(ProtocolConstant.MESSAGE_HEADER_LENGTH);
                    resultBuffer.appendBuffer(buffer);
                    //此时resultBuffer是完整的header+body
                    handler.handle(resultBuffer);
                    //清空buffer，准备下次读取
                    resultBuffer = Buffer.buffer();
                    flag = false;
                }
            }
        });
        return recordParser;
    }
}
